<?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magento.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magento.com for more information.
 *
 * @category    Mage
 * @package     Mage_Catalog
 * @copyright  Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

/**
 * API2 for catalog_product (Customer)
 *
 * @category   Mage
 * @package    Mage_Catalog
 * @author     Magento Core Team <core@magentocommerce.com>
 */
class Mage_Catalog_Model_Api2_Product_Rest_Customer_V1 extends Mage_Catalog_Model_Api2_Product_Rest
{
    /**
     * Current logged in customer
     *
     * @var Mage_Customer_Model_Customer
     */
    protected $_customer;
    protected $_category;
    protected $_brand;
    protected $_page;
    protected $_keyword;
    protected $_sort;

    protected function _retrieve()
    {
        $product = $this->_getProduct();

        //$this->_prepareProductForResponse($product);
        return $this->_formatProduct($product);
    }

    /**
     * Retrieve list of products
     *
     * @return array
     */
    protected function _retrieveCollection()
    {
        /** @var $collection Mage_Catalog_Model_Resource_Product_Collection */
        $results = array(
            'products' => array(),
            'brands' => array(),
            '_meta' => array()
        );

        $category_id = $this->getRequest()->getParam('category_id');

        if ($category_id == 14) {
            $collection = $this->getExplosionCollection();
        } elseif ($category_id == 101) {
            $collection = $this->getColaCollection();
        } else {
            $collection = $this->_getAvailableProductCollection();
            $this->_applyCategoryFilter($collection);
            $this->_applySearchFilter($collection);
        }

        if ($category_id != 101) {
            $this->_applyBrandFilter($collection);
        }

        if ($category_id != 14 || $category_id != 101) {
            $this->_applySortFilter($collection);
        }
        

        $originCollection = clone $collection;

        $meta = $this->_applyPageFilter($collection);
        if ($meta)
            $results['_meta'] = $meta;
        else
            return json_decode('{}');
        if ($category_id == 14 || $category_id == 101) {
            $results['brands'] = array();
        } else {
            $results['brands'] = $this->_getAvailableBrands($originCollection);
        }

        $products = $this->_formatProductCollection($collection);
        $results['products'] = $this->_addNewProductsToResults($products);

        return $results;
    }

    protected function getColaCollection()
    {
        $brands = array(27,51,50,324,402,52,53,499,500);
        $store = Mage::app()->getStore();
        $availableAttributes = array('brand', 'name', 'price', 'promotion', 'tag', 'special_price', 'special_from_date', 'special_to_date', 'image', 'position', 'visibility', 'status', 'promotion_image');
        $collection = Mage::getModel('catalog/product')->getCollection()->setStoreId($store->getId())
            ->addWebsiteFilter($store->getWebsiteId())
            ->addAttributeToSelect($availableAttributes)
            ->addAttributeToFilter('brand', array('in'=>$brands))
            ->addAttributeToFilter('visibility', array(
                'neq' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE))
            ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))/*->setOrder('tag', 'desc')*/
        ;
        Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
        $collection->getSelect()->distinct();
        return $collection;
    }

    protected function getExplosionCollection()
    {
        $store = Mage::app()->getStore();
        $availableAttributes = array('brand', 'name', 'price', 'promotion', 'tag', 'tag_position', 'special_price', 'special_from_date', 'special_to_date', 'image', 'position', 'visibility', 'status', 'promotion_image');
        $collection = Mage::getModel('catalog/product')->getCollection()->setStoreId($store->getId())
            ->addWebsiteFilter($store->getWebsiteId())
            ->addAttributeToSelect($availableAttributes)
            ->addAttributeToFilter('tag', Silk_Qslb_Helper_Tag::EXPLOSION)
            ->addAttributeToFilter('visibility', array(
                'neq' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE))
            ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
            ->setOrder('tag_position', 'desc');
        Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
        return $collection;
    }

    /**
     * Load product by its SKU or ID provided in request
     *
     * @return Mage_Catalog_Model_Product
     */
    protected function _getProduct()
    {
        if (is_null($this->_product)) {
            $productId = $this->getRequest()->getParam('id');
            /** @var $productHelper Mage_Catalog_Helper_Product */

            $storeId = Mage::app()->getStore()->getId();
            $productHelper = Mage::helper('catalog/product');
            $product = $productHelper->getProduct($productId, $storeId);
            if (!($product->getId())) {
                $this->_critical('商品未找到1！', Mage_Api2_Model_Resource::ERROR_CATALOG_RETRIEVE_PRODUCT_NOT_FONND);
            }
            // check if product belongs to website current
            if ($this->_getStore()->getId()) {
                $isValidWebsite = in_array($this->_getStore()->getWebsiteId(), $product->getWebsiteIds());
                if (!$isValidWebsite) {
                    $this->_critical('商品未找到2！', Mage_Api2_Model_Resource::ERROR_CATALOG_RETRIEVE_PRODUCT_NOT_FONND);
                }
            }
            // Check display settings for customers & guests
            if ($this->getApiUser()->getType() != Mage_Api2_Model_Auth_User_Admin::USER_TYPE) {
                // check if product assigned to any website and can be shown
                if ((!Mage::app()->isSingleStoreMode() && !count($product->getWebsiteIds()))
                    || !$productHelper->canShow($product)
                ) {
                    $this->_critical('商品未找到3！', Mage_Api2_Model_Resource::ERROR_CATALOG_RETRIEVE_PRODUCT_NOT_FONND);
                }
            }
            $this->_product = $product;
        }
        return $this->_product;
    }

    /**
     * Retrieve current store according to request and API user type
     *
     * @return Mage_Core_Model_Store
     */
    protected function _getStore()
    {
        $store = $this->getRequest()->getHeader('store');
        try {
            if ($this->getUserType() != Mage_Api2_Model_Auth_User_Admin::USER_TYPE) {
                // customer or guest role
                if (!$store) {
                    $store = Mage::app()->getDefaultStoreView();
                } else {
                    $store = Mage::app()->getStore($store);
                }
            } else {
                // admin role
                if (is_null($store)) {
                    $store = Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID;
                }
                $store = Mage::app()->getStore($store);
            }
        } catch (Mage_Core_Model_Store_Exception $e) {
            // store does not exist
            $this->_critical('Requested store is invalid', Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
        }
        return $store;
    }

    /**
     * Get customer group
     *
     * @return int
     */
    protected function _getCustomerGroupId()
    {
        return $this->_getCustomer()->getGroupId();
    }

    /**
     * Define product price with or without taxes
     *
     * @param float $price
     * @param bool $withTax
     * @return float
     */
    protected function _applyTaxToPrice($price, $withTax = true)
    {
        $customer = $this->_getCustomer();
        /** @var $session Mage_Customer_Model_Session */
        $session = Mage::getSingleton('customer/session');
        $session->setCustomerId($customer->getId());
        $price = $this->_getPrice($price, $withTax, $customer->getPrimaryShippingAddress(),
            $customer->getPrimaryBillingAddress(), $customer->getTaxClassId());
        $session->setCustomerId(null);

        return $price;
    }

    /**
     * Retrieve current customer
     *
     * @return Mage_Customer_Model_Customer
     */
    protected function _getCustomer()
    {
        if (is_null($this->_customer)) {
            /** @var $customer Mage_Customer_Model_Customer */
            $customer = Mage::getModel('customer/customer')->load($this->getApiUser()->getUserId());
            if (!$customer->getId()) {
                $this->_critical('登录已过期！', Mage_Api2_Model_Resource::ERROR_NOT_LOGIN);
            }
            $this->_customer = $customer;
        }
        return $this->_customer;
    }

    /**
     * @return Mage_Catalog_Model_Resource_Product_Collection $collection
     */
    protected function _getAvailableProductCollection()
    {
        $collection = Mage::getResourceModel('catalog/product_collection');
        $store = Mage::app()->getStore();
        $availableAttributes = array('brand', 'name', 'price', 'promotion', 'tag', 'special_price', 'special_from_date', 'special_to_date', 'image', 'position', 'visibility', 'status', 'promotion_image');
        $collection->setStoreId($store->getId())
            ->addAttributeToSelect($availableAttributes)
            ->addWebsiteFilter($store->getWebsiteId())
            ->addAttributeToFilter('visibility', array(
                'neq' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE))
            ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED));
        Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
        $collection->getSelect()->distinct();

        return $collection;
    }

    /**
     * @param Mage_Catalog_Model_Resource_Product_Collection $collection
     * @return array
     */
    protected function _getAvailableBrands(Mage_Catalog_Model_Resource_Product_Collection $collection)
    {
        $attributeCode = 'brand';
        $brandsValue = array_filter(array_unique($collection->getColumnValues($attributeCode)));
        $attributeModel = Mage::getSingleton('eav/config')
            ->getAttribute('catalog_product', $attributeCode)->getSource();

        $brands = array();
        foreach ($brandsValue as $brand) {
            $brands[] = array(
                'id' => $brand,
                'name' => $attributeModel->getOptionText($brand),
            );
        }

        return $brands;
    }

    /**
     * Apply filter by category id
     *
     * @param Mage_Catalog_Model_Resource_Product_Collection $collection
     */
    protected function _applyCategoryFilter(Mage_Catalog_Model_Resource_Product_Collection $collection)
    {
        $this->_category = (int)$this->getRequest()->getParam('category_id') ?: 12;
        if ($this->_category === 100) {
            $_customer = $this->_getCustomer();
            $_orders = Mage::getModel('sales/order')->getCollection()
                ->addFieldToFilter('customer_id', array('eq' => $_customer->getId()))
                ->setOrder('entity_id')->setPage(1, 3);
            $ids = array();
            foreach ($_orders as $_order) {
                $_items = $_order->getItemsCollection();
                foreach ($_items as $item) {
                    $ids[] = $item->getProductId();
                }
            }
            $collection->addAttributeToFilter('entity_id', array('in' => $ids));
        } else {
            $category = $this->_getCategoryById($this->_category);
            if (!$category->getId()) {
                $this->_critical('分类不存在！', Mage_Api2_Model_Resource::ERROR_CATALOG_RETRIEVECOLLECTION_CATEGORY_NOT_FOUND);
            }
            $collection->addCategoryFilter($category);
        }
    }

    protected function _applyBrandFilter(Mage_Catalog_Model_Resource_Product_Collection $collection)
    {
        $this->_brand = $this->getRequest()->getParam('brand');
        if ($this->_brand) {
            $attributeModel = Mage::getSingleton('eav/config')
                ->getAttribute('catalog_product', 'brand')->getSource()->getOptionText($this->_brand);
            if (!$attributeModel) {
                $this->_critical('品牌不存在！', Mage_Api2_Model_Resource::ERROR_CATALOG_RETRIEVECOLLECTION_BRAND_NOT_FOUND);
            }
            $collection->addAttributeToFilter('brand', array('eq' => $this->_brand));
        }
    }

    protected function _applySortFilter(Mage_Catalog_Model_Resource_Product_Collection $collection)
    {
        $this->_sort = strtolower($this->getRequest()->getParam('sort'));
        switch ($this->_sort) {
            case 'desc':
            case 'asc':
                $collection->getSelect()->
                joinLeft('sales_flat_order_item AS sfoi',
                    'e.entity_id = sfoi.product_id',
                    'SUM(sfoi.qty_ordered) AS ordered_qty')->group('e.entity_id')->order('ordered_qty ' . $this->_sort);
                break;
            default:
                $collection->getSelect()->
                joinLeft('sales_flat_order_item AS sfoi',
                    'e.entity_id = sfoi.product_id',
                    'SUM(sfoi.qty_ordered) AS ordered_qty')->group('e.entity_id')->order('ordered_qty desc');
                break;
        }
    }

    protected function _applySearchFilter(Mage_Catalog_Model_Resource_Product_Collection $collection)
    {
        $this->_keyword = trim(urldecode($this->getRequest()->getParam('keyword')));
        if ($this->_keyword) {
            $collection->addAttributeToFilter('name', ['like' => '%' . $this->_keyword . '%']);
        }
    }

    protected function _applyPageFilter(Mage_Catalog_Model_Resource_Product_Collection $collection)
    {
        $this->_page = abs($this->getRequest()->getParam('page')) ?: 1;
        $pageSize = abs($this->getRequest()->getParam('limit')) ?: 10;
        $count = $collection->getSize();
        $totalPages = ceil($count / $pageSize);
        $collection->setCurPage($this->_page)->setPageSize($pageSize);

        if ($count && $this->_page <= $totalPages) {
            return array(
                'totalItems' => $count,
                'totalPages' => $totalPages,
                'currentPage' => $this->_page,
                'pageSize' => $pageSize
            );
        } else {
            return false;
        }
    }

    protected function _addNewProductsToResults(array $products)
    {
        if ($this->_page == 1 && $this->_category == 12 && !$this->_keyword && !$this->_brand) {
            $_newProductCollection = $this->_getAvailableProductCollection()->setOrder('entity_id', 'DESC')->setPage(1, 2);
            $_newProductCollection->getSelect()->group('e.entity_id');
            $newProducts = $this->_formatProductCollection($_newProductCollection);
            $newIds = array();
            foreach ($newProducts as $product) {
                $newIds[] = $product['id'];
            }
            $products = array_filter($products, function ($item) use ($newIds) {
                return in_array($item['id'], $newIds) ? false : true;
            });
            $products = array_merge($newProducts, $products);
        }
        return $products;
    }

    protected function _formatProductCollection(Mage_Catalog_Model_Resource_Product_Collection $collection)
    {
        $results = array();
        $imgHelper = Mage::helper('catalog/image');
        foreach ($collection as $product) {
            if ($product->getPromotionImage()) {
                $image = $imgHelper->init($product, 'promotion_image')->resize(250) . "";
            } else {
                $image = $imgHelper->init($product, 'image')->resize(250) . "";
            }
            $results[] = array(
                'id' => (int)$product->getId(),
                'name' => $product->getName(),
                'price' => (float)$product->getPrice(),
                'special_price' => (float)$product->getFinalPrice(),
                'image' => $image,
                'promotion' => $product->getPromotion() ?: '',
                'tag' => $product->getAttributeText('tag') ? (int)$product->getResource()->getAttribute('tag')->getSource()->getOptionId($product->getAttributeText('tag')) : 0
            );
        }
        return $results;
    }

    protected function _formatProduct(Mage_Catalog_Model_Product $product)
    {
        $results = array();

        $images = array();
        $gallery = $product->getMediaGalleryImages();
        foreach ($gallery as $image) {
            $images[] = $image->getUrl();
        }

        $descriptionResult = array();
        $description = $product->getShortDescription();
        $description = Mage::helper('cms')->getBlockTemplateProcessor()->filter($description);

        preg_match_all("/<img.+?src[\s]*=[\s]*['|\"](.*?)['|\"].+?>/i", $description, $matches);
        $splits = preg_split("/<img.+?src[\s]*=[\s]*['|\"](.*?)['|\"].+?>/i", $description);
        $matchImgs = $matches[1];
        foreach ($splits as $split) {
            $result = array();
            if ($split) {
                $string = trim(strip_tags($split));
                if ($string) {
                    $result['type'] = 'string';
                    $result['content'] = $string;
                } else {
                    continue;
                }
            } else {
                $split = $matchImgs[0];
                unset($matchImgs[0]);
                $matchImgs = array_values($matchImgs);
                $result['type'] = 'image';
                $result['content'] = $split;
            }
            $descriptionResult[] = $result;
        }

        $results = array(
            'id' => (int)$product->getId(),
            'name' => $product->getName(),
            'price' => (float)$product->getPrice(),
            'special_price' => (float)$product->getFinalPrice(),
            'images' => $images,
            'promotion' => $product->getPromotion() ?: '',
            'tag' => $product->getAttributeText('tag') ? (int)$product->getResource()->getAttribute('tag')->getSource()->getOptionId($product->getAttributeText('tag')) : 0,
            'description' => $descriptionResult,
            'related' => $this->_getRelatedProducts($product->getBrand(), $product->getId()),
        );

        return $results;
    }

    protected function _getRelatedProducts($brand, $id)
    {
        $collection = $this->_getAvailableProductCollection()
            ->addAttributeToFilter('brand', $brand)
            ->addAttributeToFilter('entity_id', array('neq' => $id))
            ->setPage(1, 4);
        return $this->_formatProductCollection($collection);
    }
}
